import {
    request,
    AbstractBookCrawler,
    BasicBook,
    SearchBookResult,
    Book,
    BasicChapter,
    BookCrawlerTest,
    BookSource,
    htmlToString,
    RequestOptions,
    delayed,
    removeQuerySelector,
    removeLinesContaining,
} from "../../common/common_node.js";

class BookCrawler extends AbstractBookCrawler {
    options = new RequestOptions({
        ignoreUserAgent: true,
        headers: {
            "accept-language": "zh-CN,zh;q=0.9"
        }
    });

    async searchBook(keyword, pageNum) {

        const res = (await request(`${this.source.searchBaseUrl}/user/hm.html?q=${encodeURIComponent(keyword)}`));

        let cookie_hm = null;

        if(res.headers && res.headers['set-cookie']){
            const cookies = res.headers['set-cookie'].split(';');
            for (let cookie of cookies) {
                cookie = cookie.trim();
                const cookieArr = cookie.split('=');
                if (cookieArr[0] === 'hm') {
                    cookie_hm = cookie;
                }
            }
            await delayed(2 * 1000)
        }
        let jsonArr = null;
        for (let i = 0; i < 10; i++) {

            jsonArr = await (await request(`${this.source.searchBaseUrl}/user/search.html?q=${encodeURIComponent(keyword)}`, new RequestOptions({
                ignoreUserAgent: true,
                headers: {
                    ...this.options.headers,
                    "Cookie": cookie_hm
                }
            }))).json();
            if (jsonArr.toString() !== '1') {
                break;
            }
            await delayed(2 * 1000)
        }

        if (jsonArr.toString() === '1') {
            return new SearchBookResult({
                pageNum: pageNum, pages: 1, keyword: keyword, bookList: []
            });
        }

        const bookArr = [];
        for (const json of jsonArr) {
            bookArr.push(new BasicBook({
                name: json.articlename, author: json.author, path: json.url_list,
            }))
        }

        return new SearchBookResult({
            pageNum: pageNum, pages: 1, keyword: keyword, bookList: bookArr
        });
    }

    async bookDetails(path) {

        const $ = await (await request(this.source.bookBaseUrl + path, this.options)).doc();

        const intro = removeQuerySelector($('.intro dd'), [".allshow"]);

        return new Book({
            name: $('[property="og:novel:book_name"]').attr("content"),
            author: $('[property="og:novel:author"]').attr("content"),
            path: path,
            intro: intro.text().replace(/2w0-\d+/g, '').trim(),
            coverUrl: $('[property="og:image"]').attr("content"),
            type: $('[property="og:novel:category"]').attr("content"),
        });
    }

    async bookCatalog(path) {

        const $ = await (await request(this.source.bookBaseUrl + path, this.options)).doc();
        const dl = removeQuerySelector($(".listmain dl"), ["dd.more.pc_none"]);
        const aList = dl.find("dd a");
        const catalog = [];
        aList.each(function (i, e) {
            catalog.push(new BasicChapter({
                index: i, title: $(e).text(), path: $(e).attr("href")
            }))
        })
        return catalog;
    }

    async chapterContent(path) {
        const $ = await (await request(this.source.bookBaseUrl + path, this.options)).doc();

        const title = $('h1.wap_none').text();

        const contentElement = removeQuerySelector($(".ReadAjax_content"), ["div", "a", "p", "font"]);
        return removeLinesContaining(htmlToString(contentElement.html()).replace(/^.*请收藏本站.*$/gm, '').trim(),title.replace(' ',''));
    }
}

const source = {
    "id": "free_book_dart/1",
    "name": "笔趣阁",
    "portalUrl": "https://www.mfbqg.com",
    "searchBaseUrl": "https://www.mfbqg.com",
    "bookBaseUrl": "https://www.mfbqg.com",
    "active": true
};

await new BookCrawlerTest(new BookCrawler(BookSource.createTestBookSource(source)), {
    enableSearch: true, keyword: "大明国师"
}).run();